package cn.iocoder.yudao.hires.service.notice.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.hires.entity.NoticeInterviewDO;
import cn.iocoder.yudao.hires.mapper.NoticeApplicationMapper;
import cn.iocoder.yudao.hires.mapper.NoticeEnterpriseMapper;
import cn.iocoder.yudao.hires.mapper.NoticeInterviewMapper;
import cn.iocoder.yudao.hires.service.notice.NoticeInterviewService;
import cn.iocoder.yudao.hires.vo.PostTionShortVo;
import cn.iocoder.yudao.hires.vo.noticeinterview.CalendarVo;
import cn.iocoder.yudao.hires.vo.noticeinterview.NoticeInterviewPageReqVO;
import cn.iocoder.yudao.hires.vo.noticeinterview.NoticeInterviewSaveReqVO;
import cn.iocoder.yudao.im.service.NoticeImMessageService;
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
import cn.iocoder.yudao.module.system.service.tenant.TenantService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.NOT_EXISTS;

/**
 * 下游-面试邀约 Service 实现类
 *
 * @author 超级管理员
 */
@Service
@Validated
public class NoticeInterviewServiceImpl implements NoticeInterviewService {

    @Resource
    NoticeImMessageService noticeImMessageService;
    @Resource
    private NoticeInterviewMapper noticeInterviewMapper;
    @Resource
    private TenantService tenantService;
    @Resource
    private NoticeApplicationMapper noticeApplicationMapper;
    @Override
    public Long createNoticeInterview(NoticeInterviewSaveReqVO createReqVO) {
        // 插入
        NoticeInterviewDO noticeInterview = BeanUtils.toBean(createReqVO, NoticeInterviewDO.class);
        PostTionShortVo category = noticeApplicationMapper.getCategory(noticeInterview.getPositionId());
        noticeInterview.setPositionCategoryId(category.getCategoryId());
        noticeInterview.setPositionCategoryName(category.getCategoryName());
        noticeInterviewMapper.insert(noticeInterview);
        // 返回
        return noticeInterview.getId();
    }

    @Override
    public void updateNoticeInterview(NoticeInterviewSaveReqVO updateReqVO) {
        // 校验存在
        validateNoticeInterviewExists(updateReqVO.getId());
        // 更新
        NoticeInterviewDO updateObj = BeanUtils.toBean(updateReqVO, NoticeInterviewDO.class);
        noticeInterviewMapper.updateById(updateObj);
    }

    @Override
    public void deleteNoticeInterview(Long id) {
        // 校验存在
        validateNoticeInterviewExists(id);
        // 删除
        noticeInterviewMapper.deleteById(id);
    }

    private void validateNoticeInterviewExists(Long id) {
        if (noticeInterviewMapper.selectById(id) == null) {
            throw exception(NOT_EXISTS);
        }
    }

    @Override
    public NoticeInterviewDO getNoticeInterview(Long id) {
        return noticeInterviewMapper.selectById(id);
    }

    @Override
    public PageResult<NoticeInterviewDO> getNoticeInterviewPage(NoticeInterviewPageReqVO pageReqVO) {
        return noticeInterviewMapper.selectPage(pageReqVO);
    }

    @Override
    public List<NoticeInterviewDO> getNoticeInterviewList(Long userId, Integer positionId, String positionName, Long tenantId, Long status, String interviewStartTime) {
        return noticeInterviewMapper.getNoticeInterviewList(positionId,positionName,tenantId,userId,status,interviewStartTime);
    }

    @Override
    public Map<String, Long> getNum(Long userId, Long tenantId) {

        Map<String, Long> num = new HashMap<>();
        // 面试
        num.put("numberOfInterviews", noticeInterviewMapper.getNumberOfInterviews(userId, tenantId));
        //投递记录
        num.put("numberOfDeliveries", noticeInterviewMapper.getNumberOfDeliveries(userId, tenantId));
        //沟通
        num.put("communicateCount", ObjectUtil.isNotEmpty(noticeImMessageService.getCommunicateCount(userId)) ? noticeImMessageService.getCommunicateCount(userId) : 0L);
        return num;
    }

    @Override
    public void updateNoticeInterviewStatus(Long id,Integer status) {
        NoticeInterviewDO noticeInterview = noticeInterviewMapper.selectById(id);
        noticeInterview.setStatus(status);
        noticeInterviewMapper.updateById(noticeInterview);
    }


    @Override
    public List<CalendarVo> SeekInterviewCalendarFlag(Long userId, Long tenantId, String yearMonth) {
        if (!yearMonth.matches("\\d{4}-\\d{2}")) {
            throw new IllegalArgumentException("日期格式应为YYYY-MM");
        }
        // 解析年月，获取该月的天数
        YearMonth ym = YearMonth.parse(yearMonth, DateTimeFormatter.ofPattern("yyyy-MM"));
        LocalDate startDate = ym.atDay(1);
        LocalDate endDate = ym.atEndOfMonth();
        //  查询数据库获取该月的所有面试记录
        List<NoticeInterviewDO> interviews = noticeInterviewMapper.selectByUserIdAndTenantIdAndDateRange(userId, tenantId, startDate.atStartOfDay(), endDate.atTime(23, 59, 59));
        // 按日期分组面试记录
        Map<LocalDate, List<NoticeInterviewDO>> interviewsByDate = interviews.stream().collect(Collectors.groupingBy(interview -> interview.getInterviewStartTime().toLocalDate()));
        // 准备返回结果
        List<CalendarVo> result = new ArrayList<>();
        // 遍历该月每一天
        for (LocalDate day = startDate; !day.isAfter(endDate); day = day.plusDays(1)) {
            CalendarVo vo = new CalendarVo();
            vo.setDateString(day.format(DateTimeFormatter.ISO_LOCAL_DATE));
            //  检查当天是否有面试记录
            if (interviewsByDate.containsKey(day)) {
                List<NoticeInterviewDO> dayInterviews = interviewsByDate.get(day);
                List<TenantDO> tenantDOs = new ArrayList<>();

                //  转换面试记录为TenantDO
                for (NoticeInterviewDO interview : dayInterviews) {
                    TenantDO tenant = tenantService.getTenant(interview.getTenantId());
                    if (BeanUtil.isNotEmpty(tenant)) {
                        tenantDOs.add(tenant);
                    }
                }
                vo.setIsToday(true);
                // 按时间排序
                dayInterviews.sort(Comparator.comparing(NoticeInterviewDO::getInterviewStartTime));

                vo.setTimeString(dayInterviews.get(0).getInterviewStartTime().format(DateTimeFormatter.ofPattern("HH:mm")));
                vo.setTenantDOs(tenantDOs);
            } else {
                vo.setIsToday(false);
                vo.setTimeString("");
                vo.setTenantDOs(Collections.emptyList());
            }
            result.add(vo);
        }
        return result;
    }


    /**
     * 给入年月日  返回当前的面试
     *
     * @param userId   用户id
     * @param tenantId 租户id
     * @param date     年月
     * @return 面试日历的东西
     */
    @Override
    public List<NoticeInterviewDO> interviewCalendar(Long userId, Long tenantId, String date) {
        LocalDate parsedDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        List<NoticeInterviewDO> interviews = noticeInterviewMapper.selectByUserIdAndTenantIdAndDateRange(userId, tenantId, parsedDate.atTime(0, 0, 0), parsedDate.atTime(23, 59, 59));
        if (CollUtil.isNotEmpty(interviews)) {
            //  转换面试记录为TenantDO
            for (NoticeInterviewDO interview : interviews) {
                TenantDO tenant = tenantService.getTenant(interview.getTenantId());
                if (BeanUtil.isNotEmpty(tenant)) {
                    interview.setLogoUrl(tenant.getLogoUrl());
                    interview.setTenantName(tenant.getName());
                    interview.setIndustryName(tenant.getIndustryName());
                    interview.setCompanyNatureName(tenant.getCompanyNatureName());
                    interview.setCompanyScaleName(tenant.getCompanyScaleName());
                }
            }
            return interviews;
        } else {
            return new ArrayList<>();
        }
    }

}
